package com.xs.server;

import java.util.concurrent.TimeUnit;

import com.xs.SimpleDecoder;
import com.xs.SimpleEncoder;
import com.xs.client.entity.RpcRequest;
import com.xs.client.entity.RpcResponse;
import com.xs.constant.NettyConstants;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;

public final class NettyServer {
	private int port = 9999;
	private EventLoopGroup bossGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors() * 2);
	private EventLoopGroup workGroup = new NioEventLoopGroup(10);

	/**
	 * 启动服务器
	 */
	public NettyServer(int port) {
		if (port != 0) {
			this.port = port;
		}

	}

	public void start() {
		ServerBootstrap boot = new ServerBootstrap();
		boot.group(bossGroup, workGroup);
		boot.channel(NioServerSocketChannel.class);
		boot.handler(new LoggingHandler(LogLevel.INFO));
		boot.childHandler(new ChannelInitializer<SocketChannel>() {

			@Override
			protected void initChannel(SocketChannel ch) throws Exception {
				ChannelPipeline pipeline = ch.pipeline();
				//服务端心跳检测
		        pipeline.addLast(new IdleStateHandler(
		                NettyConstants.SERVER_READ_IDEL_TIME_OUT,
		                NettyConstants.SERVER_WRITE_IDEL_TIME_OUT, 
		                NettyConstants.SERVER_ALL_IDEL_TIME_OUT,
		                TimeUnit.SECONDS));
				
				
				// pipeline.addLast(new
				// DelimiterBasedFrameDecoder(10,Delimiters.lineDelimiter()));
				// pipeline.addLast(new StringEncoder());
				// pipeline.addLast(new StringDecoder());

				pipeline.addLast(new SimpleEncoder(RpcResponse.class));
				pipeline.addLast(new SimpleDecoder(RpcRequest.class));
				pipeline.addLast(new ServerHandler());
			}

		});

		try {
			ChannelFuture future = boot.bind(port);

			future.channel().closeFuture().sync();
		} catch (InterruptedException e) {

			e.printStackTrace();
		} finally {
			bossGroup.shutdownGracefully();
			workGroup.shutdownGracefully();
		}

	}

	
	public static void main(String[] args) {
		new NettyServer(8888).start();
	}
	
	public void init() {

		new Thread(() -> {
			start();
		}).start();
		;

	}

}
